home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Programming / SWI / source / boot / init.pl < prev    next >
Encoding:
Text File  |  1998-02-04  |  33.2 KB  |  1,276 lines

  1. /*  $Id: init.pl,v 1.47 1998/02/04 16:20:45 jan Exp $
  2.  
  3.     Copyright (c) 1990 Jan Wielemaker. All rights reserved.
  4.     jan@swi.psy.uva.nl
  5.  
  6.     Purpose: Get the Ball Rolling ...
  7. */
  8.  
  9. /*
  10. Consult, derivates and basic things.   This  module  is  loaded  by  the
  11. C-written  bootstrap  compiler.
  12.  
  13. The $:- directive  is  executed  by  the  bootstrap  compiler,  but  not
  14. inserted  in  the  intermediate  code  file.   Used  to print diagnostic
  15. messages and start the Prolog defined compiler for  the  remaining  boot
  16. modules.
  17.  
  18. If you want  to  debug  this  module,  put  a  '$:-'  trace.   directive
  19. somewhere.   The  tracer will work properly under boot compilation as it
  20. will use the C defined write predicate  to  print  goals  and  does  not
  21. attempt to call the Prolog defined trace interceptor.
  22. */
  23.  
  24. '$:-' format('Loading boot file ...~n', []).
  25.  
  26.         /********************************
  27.         *    LOAD INTO MODULE SYSTEM    *
  28.         ********************************/
  29.  
  30. :- $set_source_module(_, system).
  31.  
  32.         /********************************
  33.         *          DIRECTIVES           *
  34.         *********************************/
  35.  
  36. op(_, _, []) :- !.
  37. op(Priority, Type, [Name|Rest]) :- !,
  38.     $op(Priority, Type, Name),
  39.     op(Priority, Type, Rest).
  40. op(Priority, Type, Name) :-
  41.     $op(Priority, Type, Name).
  42.  
  43. dynamic((Spec, More)) :- !,
  44.     dynamic(Spec),
  45.     dynamic(More).
  46. dynamic(Spec) :-
  47.     $set_predicate_attribute(Spec, (dynamic), 1).
  48.  
  49. multifile((Spec, More)) :- !,
  50.     multifile(Spec),
  51.     multifile(More).
  52. multifile(Spec) :-
  53.     $set_predicate_attribute(Spec, (multifile), 1).
  54.  
  55. module_transparent((Spec, More)) :- !,
  56.     module_transparent(Spec),
  57.     module_transparent(More).
  58. module_transparent(Spec) :-
  59.     $set_predicate_attribute(Spec, transparent, 1).
  60.  
  61. discontiguous((Spec, More)) :- !,
  62.     discontiguous(Spec),
  63.     discontiguous(More).
  64. discontiguous(Spec) :-
  65.     $set_predicate_attribute(Spec, (discontiguous), 1).
  66.  
  67. volatile((Spec, More)) :- !,
  68.     volatile(Spec),
  69.     volatile(More).
  70. volatile(Spec) :-
  71.     $set_predicate_attribute(Spec, (volatile), 1).
  72.  
  73. :- module_transparent
  74.     (dynamic)/1,
  75.     (multifile)/1,
  76.     (module_transparent)/1,
  77.     (discontiguous)/1,
  78.     (volatile)/1,
  79.     $hide/2,
  80.     $show_childs/2.
  81.  
  82.  
  83.         /********************************
  84.         *        TRACE BEHAVIOUR        *
  85.         *********************************/
  86.  
  87. %    $hide(+Name, +Arity)
  88. %    Predicates protected this way are never visible in the tracer.
  89.  
  90. $hide(Name, Arity) :-
  91.     $set_predicate_attribute(Name/Arity, trace, 0).
  92.  
  93. %    $show_childs(+Name, +Arity)
  94. %    Normally system predicates hide their childs frames if these are
  95. %    system predicates as well.  $show_childs suppresses this.
  96.  
  97. $show_childs(Name, Arity) :-  
  98.         $set_predicate_attribute(Name/Arity, hide_childs, 0).
  99.  
  100.         /********************************
  101.         *       CALLING, CONTROL        *
  102.         *********************************/
  103.  
  104. :- module_transparent
  105.     ';'/2,
  106.     '|'/2,
  107.     ','/2,
  108.     call/1,
  109.     call/2,
  110.     call/3,
  111.     call/4,
  112.     call/5,
  113.     call/6,
  114.     (^)/2,
  115.     (not)/1,
  116.     (\+)/1,
  117.     (->)/2,
  118.     (*->)/2,
  119.     once/1,
  120.     ignore/1,
  121.     block/3,
  122.     catch/3,
  123.     apply/2.
  124.  
  125. %   ->/2, ;/2, |/2 and \+/1 are normally compiled. These predicate catch them
  126. %   in case they are called via the meta-call predicates.
  127.  
  128. (If ->  Then) :- If, !, Then.
  129. (If *-> Then) :- (If *-> Then ; fail).
  130.  
  131. (If ->  Then; Else) :- !, (If  -> Then ; Else).
  132. (If *-> Then; Else) :- !, (If *-> Then ; Else).
  133. (A ; B) :- (A ; B).
  134.  
  135. (If ->  Then| Else) :- !, (If  -> Then ; Else).
  136. (If *-> Then| Else) :- !, (If *-> Then ; Else).
  137. (A | B) :- (A ; B).
  138.  
  139. ','(Goal1, Goal2) :-            % Puzzle for beginners!
  140.     Goal1,
  141.     Goal2.
  142.  
  143. call(Goal) :-                % make these available as predicates
  144.     Goal.
  145. call(G, A) :-
  146.     call(G, A).
  147. call(G, A, B) :-
  148.     call(G, A, B).
  149. call(G, A, B, C) :-
  150.     call(G, A, B, C).
  151. call(G, A, B, C, D) :-
  152.     call(G, A, B, C, D).
  153. call(G, A, B, C, D, E) :-
  154.     call(G, A, B, C, D, E).
  155.  
  156. not(Goal) :-
  157.     \+ Goal.
  158.  
  159. %    This version of not is compiled as well. For meta-calls only
  160.  
  161. \+ Goal :-
  162.     \+ Goal.
  163.  
  164. %    once/1 can normally be replaced by ->/2. For historical reasons
  165. %    only.
  166.  
  167. once(Goal) :-
  168.     Goal, !.
  169.  
  170. ignore(Goal) :-
  171.     Goal, !.
  172. ignore(_Goal).
  173.  
  174. apply(Pred, Arguments) :-
  175.     $apply(Pred, Arguments).        % handled by the compiler
  176.  
  177. _Var^Goal :-                    % setof/3, bagof/3
  178.     Goal.
  179.  
  180. %    block/3, !/1, exit/2, fail/1
  181. %    `longjmp' like control-structures.  See manual.  The predicate
  182. %    system:block/3 is used by the VMI's I_CUT_BLOCK and B_EXIT.
  183. %    $exit and $cut are interpreted by the compiler/decompiler,
  184. %    just like $apply/2.
  185.  
  186. block(_Label, Goal, _RVal) :-
  187.     Goal.
  188.  
  189. !(Label) :-
  190.     $cut(Label).                % handled by compiler
  191.  
  192. exit(Label, RVal) :-
  193.     $exit(Label, RVal).            % handled by compiler
  194.  
  195. fail(Label) :-
  196.     $cut(Label),                % handled by compiler
  197.     fail.
  198.  
  199. %    catch(:Goal, +Catcher, :Recover)
  200. %    throw(+Exception)
  201. %
  202. %    ISO compliant exception handling.  $throw/1 is compiled to
  203. %    rhe virtual instruction B_THROW.  See pl-wam.c for details.
  204.  
  205. catch(Goal, _Catcher, _Recover) :-
  206.     Goal.
  207.  
  208. throw(Exception) :-
  209.     $throw(Exception).
  210.  
  211. :-
  212.     $hide((';'), 2),
  213.     $hide(('|'), 2),
  214.     $hide((','), 2),
  215.     $hide((->), 2),
  216.     $show_childs(^, 2),
  217.     $show_childs(call, 1),
  218.     $show_childs(call, 2),
  219.     $show_childs(call, 3),
  220.     $show_childs(call, 4),
  221.     $show_childs(call, 5),
  222.     $show_childs(call, 6),
  223.     $show_childs(not, 1),
  224.     $show_childs(\+, 1),
  225.     $show_childs(once, 1),
  226.     $show_childs(ignore, 1),     
  227.     $show_childs((','), 2),     
  228.     $show_childs((';'), 2),     
  229.     $show_childs(('|'), 2),
  230.     $show_childs(block, 3),
  231.     $show_childs((->), 2).
  232.  
  233.  
  234.         /********************************
  235.         *            MODULES            *
  236.         *********************************/
  237.  
  238. %    $prefix_module(+Module, +Context, +Term, -Prefixed)
  239. %    Tags `Term' with `Module:' if `Module' is not the context module.
  240.  
  241. $prefix_module(Module, Module, Head, Head) :- !.
  242. $prefix_module(Module, _, Head, Module:Head).
  243.  
  244.  
  245.         /********************************
  246.         *      TRACE AND EXCEPTIONS     *
  247.         *********************************/
  248.  
  249. :- user:dynamic((exception/3,
  250.          prolog_event_hook/1)).
  251. :- user:multifile((exception/3,
  252.            prolog_event_hook/1)).
  253.  
  254. %    This function is called from C on undefined predicates.  First
  255. %    allows the user to take care of it using exception/3. Else try
  256. %    to give a DWIM warning. Otherwise fail. C will print an error
  257. %    message.
  258.  
  259. :- flag($verbose_autoload, _, off).
  260. :- flag($enable_autoload, _, on).
  261. :- flag($autoloading, _, 0).
  262.  
  263. $undefined_procedure(Module, Name, Arity, Action) :-
  264.     $prefix_module(Module, user, Name/Arity, Pred),
  265.     user:exception(undefined_predicate, Pred, Action), !.
  266. $undefined_procedure(Module, Name, Arity, retry) :-
  267.     flag($enable_autoload, on, on),
  268.     $find_library(Module, Name, Arity, LoadModule, Library),
  269.     functor(Head, Name, Arity),
  270.     flag($autoloading, Old, Old+1),
  271.     (   Module == LoadModule
  272.     ->  ignore(ensure_loaded(Library))
  273.     ;   (   $c_current_predicate(_, LoadModule:Head)
  274.         ->    Module:import(LoadModule:Head)
  275.         ;    ignore(Module:use_module(Library, [Name/Arity]))
  276.         )
  277.     ),
  278.     flag($autoloading, _, Old),
  279.     $c_current_predicate(_, Module:Head).
  280. $undefined_procedure(_, _, _, fail).
  281.  
  282. $calleventhook(Term) :-
  283.     (   notrace(user:prolog_event_hook(Term))
  284.     ->  true
  285.     ;   true
  286.     ).
  287.  
  288. :- $hide($calleventhook, 1).
  289.  
  290.  
  291.         /********************************
  292.         *        SYSTEM MESSAGES        *
  293.         *********************************/
  294.  
  295. %    $ttyformat(+Format, [+ArgList])
  296. %    Format on the user stream.  Used to print system messages.
  297.  
  298. $ttyformat(Format) :-
  299.     $ttyformat(Format, []).
  300. $ttyformat(Format, Args) :-
  301.     format(user_error, Format, Args).
  302.  
  303. %    $confirm(Format, Args)
  304. %
  305. %    Ask the user to confirm a question.
  306.  
  307. $confirm(Format, Args) :-
  308.     $ttyformat(Format, Args),
  309.     $ttyformat('? '),
  310.     between(0, 5, _),
  311.         (   get_single_char(Answer),
  312.         memberchk(Answer, [0'y, 0'Y, 0'j, 0'J, 0'n, 0'N, 0' ,10])
  313.         ->  !, $confirm_(Answer)
  314.         ;   $ttyformat('Please answer ''y'' or ''n''~n'),
  315.         fail
  316.         ).
  317.  
  318. $confirm_(Answer) :-
  319.     memberchk(Answer, [0'y, 0'Y, 0'j, 0'J, 0' ,10]), !,
  320.     (   $tty
  321.     ->  $ttyformat('yes~n')
  322.     ;   true
  323.     ).
  324. $confirm_(_) :-
  325.     $tty,
  326.     $ttyformat('no~n'),
  327.     fail.
  328.  
  329. %    $warning(+Format, [+ArgList])
  330. %    Format a standard warning to the user and start the tracer.
  331.  
  332. $warning(Format) :-
  333.     $warning(Format, []).
  334. $warning(Format, Args) :-
  335.     source_location(File, Line), !,
  336.     (   feature(report_error, true)
  337.     ->  sformat(Msg, Format, Args),
  338.         (   user:exception(warning, warning(File, Line, Msg), _)
  339.         ->  true
  340.         ;   format(user_error, '[WARNING: (~w:~d)~n~t~8|~w]~n',
  341.                [File, Line, Msg])
  342.         )
  343.     ;   true
  344.     ).
  345. $warning(Format, Args) :-
  346.     (   feature(report_error, true)
  347.     ->  format(user_error, '[WARNING: ', []), 
  348.         format(user_error, Format, Args), 
  349.         format(user_error, ']~n', [])
  350.     ;   true
  351.     ),
  352.     (   feature(debug_on_error, true)
  353.     ->  trace
  354.     ;   true
  355.     ).
  356.  
  357.  
  358. %    $warn_undefined(+Goal, +Dwims)
  359. %    Tell the user that the predicate implied by `Goal' does not exists,
  360. %    If there are alternatives (DWIM) tell the user about them.
  361.  
  362. :- module_transparent
  363.     $warn_undefined/2,
  364.     $write_alternatives/1,
  365.     $predicate_name/2.
  366.  
  367. $warn_undefined(Goal, Dwims) :-
  368.     $predicate_name(Goal, Name),
  369.     $ttyformat('[WARNING: Undefined predicate: `~w''', [Name]),
  370.     (   Dwims == []
  371.     ;   $ttyformat('~nHowever there are definitions for:'), 
  372.         $write_alternatives(Dwims)
  373.     ), !,
  374.     $ttyformat(']~n').
  375.  
  376. $write_alternatives([]) :- !.
  377. $write_alternatives([Dwim|Rest]) :-
  378.     $predicate_name(Dwim, Name), 
  379.     $ttyformat('~n~t~8|~w', [Name]), 
  380.     $write_alternatives(Rest).
  381.  
  382. %    $predicate_name(+Head, -String)
  383. %    Convert `Head' into a predicate name.
  384.  
  385. $predicate_name(Goal, String) :-
  386.     $strip_module(Goal, Module, Head), 
  387.     functor(Head, Name, Arity), 
  388.     (   memberchk(Module, [user, system])
  389.     ->  sformat(String, '~w/~w',    [Name, Arity])
  390.     ;   sformat(String, '~w:~w/~w',    [Module, Name, Arity])
  391.     ).
  392.  
  393.  
  394. :- dynamic
  395.     user:portray/1.
  396. :- multifile
  397.     user:portray/1.
  398.     
  399.  
  400.          /*******************************
  401.          *     FILE_SEARCH_PATH    *
  402.          *******************************/
  403.  
  404. :- dynamic user:file_search_path/2.
  405. :- multifile user:file_search_path/2.
  406.  
  407. user:file_search_path(library, Dir) :-
  408.     library_directory(Dir).
  409. user:file_search_path(swi, Home) :-
  410.     feature(home, Home).
  411. user:file_search_path(foreign, swi(ArchLib)) :-
  412.     feature(arch, Arch),
  413.     concat('lib/', Arch, ArchLib).
  414. user:file_search_path(foreign, swi(lib)).
  415.  
  416. expand_file_search_path(Spec, Expanded) :-
  417.     functor(Spec, Alias, 1),
  418.     user:file_search_path(Alias, Exp0),
  419.     expand_file_search_path(Exp0, Exp1),
  420.     arg(1, Spec, Base),
  421.     $make_path(Exp1, Base, Expanded).
  422. expand_file_search_path(Spec, Spec) :-
  423.     atomic(Spec).
  424.  
  425. $make_path(Dir, File, Path) :-
  426.     concat(_, /, Dir), !,
  427.     concat(Dir, File, Path).
  428. $make_path(Dir, File, Path) :-
  429.     $concat_atom([Dir, '/', File], Path).
  430.  
  431.  
  432.         /********************************
  433.         *         FILE CHECKING         *
  434.         *********************************/
  435.  
  436. %    File is a specification of a Prolog source file. Return the full
  437. %    path of the file.
  438.  
  439. $check_file(0, _) :- !, fail.            % deal with variables
  440. $check_file(user, user) :- !.
  441. $check_file(File, Absolute) :-
  442.     flag($compiling, database, database), !,
  443.     $chk_file(File, ['.qlf', '.pl', ''], exists, Absolute).
  444. $check_file(File, Absolute) :-
  445.     $chk_file(File, ['.pl', ''], exists, Absolute).
  446.  
  447. $chk_file(Spec, Extensions, Cond, FullName) :-
  448.     $canonise_extensions(Extensions, Exts),
  449.     $dochk_file(Spec, Exts, Cond, FullName).
  450.  
  451. $dochk_file(Spec, Extensions, Cond, FullName) :-
  452.     functor(Spec, Alias, 1),
  453.     user:file_search_path(Alias, _), !,
  454.     $chk_alias_file(Spec, Extensions, Cond, FullName).
  455. $dochk_file(Term, Ext, Cond, FullName) :-    % allow a/b, a-b, etc.
  456.     \+ atomic(Term), !,
  457.     term_to_atom(Term, Raw),
  458.     atom_chars(Raw, S0),
  459.     delete(S0, 0' , S1),
  460.     atom_chars(Atom, S1),
  461.     $dochk_file(Atom, Ext, Cond, FullName).
  462. $dochk_file(File, Exts, Cond, FullName) :-
  463.     is_absolute_file_name(File), !,
  464.     $extend_file(File, Exts, Extended),
  465.     $file_condition(Cond, Extended),
  466.     $absolute_file_name(Extended, FullName).
  467. $dochk_file(File, Exts, Cond, FullName) :-
  468.     source_location(ContextFile, _Line),
  469.     file_directory_name(ContextFile, ContextDir),
  470.     $concat_atom([ContextDir, /, File], AbsFile),
  471.     $extend_file(AbsFile, Exts, Extended),
  472.     $file_condition(Cond, Extended), !,
  473.     $absolute_file_name(Extended, FullName).
  474. $dochk_file(File, Exts, Cond, FullName) :-
  475.     $extend_file(File, Exts, Extended),
  476.     $file_condition(Cond, Extended),
  477.     $absolute_file_name(Extended, FullName).
  478.  
  479. :- dynamic
  480.     $search_path_file_cache/4.
  481. :- volatile
  482.     $search_path_file_cache/4.
  483.  
  484. $chk_alias_file(Spec, Exts, Cond, FullFile) :-
  485.     $search_path_file_cache(Spec, Cond, FullFile, Exts).
  486. $chk_alias_file(Spec, Exts, Cond, FullFile) :-
  487.     expand_file_search_path(Spec, Expanded),
  488.     $extend_file(Expanded, Exts, LibFile),
  489.     $file_condition(Cond, LibFile),
  490.     $absolute_file_name(LibFile, FullFile),
  491.     \+ $search_path_file_cache(Spec, Cond, FullFile, Exts),
  492.     asserta($search_path_file_cache(Spec, Cond, FullFile, Exts)).
  493.     
  494. $file_condition([], _) :- !.
  495. $file_condition([H|T], File) :- !,
  496.     $file_condition(H, File),
  497.     $file_condition(T, File).
  498. $file_condition(exists, File) :- !,
  499.     exists_file(File).
  500. $file_condition(file_type(directory), File) :- !,
  501.     exists_directory(File).
  502. $file_condition(file_type(file), File) :- !,
  503.     exists_file(File),
  504.     \+ exists_directory(File).
  505. $file_condition(access([A1|AT]), File) :- !,
  506.     $file_condition(access(A1), File),
  507.     $file_condition(access(AT), File).
  508. $file_condition(access([]), _) :- !.
  509. $file_condition(access(Access), File) :- !,
  510.     access_file(File, Access).
  511.  
  512. $extend_file(File, Exts, FileEx) :-
  513.     $ensure_extensions(Exts, File, Fs),
  514.     $list_to_set(Fs, FsSet),
  515.     member(FileEx, FsSet).
  516.     
  517. $ensure_extensions([], _, []).
  518. $ensure_extensions([E|E0], F, [FE|E1]) :-
  519.     file_name_extension(F, E, FE),
  520.     $ensure_extensions(E0, F, E1).
  521.  
  522. $list_to_set([], []).
  523. $list_to_set([H|T], R) :-
  524.     memberchk(H, T), !, 
  525.     $list_to_set(T, R).
  526. $list_to_set([H|T], [H|R]) :-
  527.     $list_to_set(T, R).
  528.  
  529. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  530. Canonise the extension list. Old SWI-Prolog   require  `.pl', etc, which
  531. the Quintus compatibility  requests  `pl'.   This  layer  canonises  all
  532. extensions to .ext
  533. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  534.  
  535. $canonise_extensions([], []) :- !.
  536. $canonise_extensions([H|T], [CH|CT]) :- !,
  537.     $canonise_extension(H, CH),
  538.     $canonise_extensions(T, CT).
  539. $canonise_extensions(E, [CE]) :-
  540.     $canonise_extension(E, CE).
  541.  
  542. $canonise_extension('', '') :- !.
  543. $canonise_extension(DotAtom, DotAtom) :-
  544.     concat('.', _, DotAtom), !.
  545. $canonise_extension(Atom, DotAtom) :-
  546.     concat('.', Atom, DotAtom).
  547.  
  548.  
  549.         /********************************
  550.         *            CONSULT            *
  551.         *********************************/
  552.  
  553. :- user:(dynamic
  554.          library_directory/1,
  555.         $start_compilation/2,
  556.         $end_compilation/2).
  557. :- user:(multifile
  558.          library_directory/1,
  559.         $start_compilation/2,
  560.         $end_compilation/2).
  561.  
  562.  
  563. :-    flag($break_level,    _, 0),
  564.     flag($compiling,    _, database),
  565.     flag($preprocessor,    _, none),
  566.     prompt(_, '|: ').
  567.  
  568. %    compiling
  569. %    Is true if SWI-Prolog is generating an intermediate code file
  570.  
  571. compiling :-
  572.     \+ flag($compiling, database, database).
  573.  
  574. :- module_transparent
  575.     $ifcompiling/1.
  576.  
  577. $ifcompiling(_) :-
  578.     flag($compiling, database, database), !.
  579. $ifcompiling(G) :-
  580.     G.
  581.  
  582.         /********************************
  583.         *         PREPROCESSOR          *
  584.         *********************************/
  585.  
  586. preprocessor(Old, New) :-
  587.     flag($preprocessor, Old, New).
  588.  
  589. $open_source(File, Goal) :-
  590.     preprocessor(none, none), !,
  591.     seeing(Old), see(File),
  592.     $open_source_call(File, Goal, True),
  593.     seen, see(Old),
  594.     True == yes.
  595. $open_source(File, Goal) :-
  596.     preprocessor(Pre, Pre),
  597.     (   $substitute_atom('%f', File, Pre, Command)
  598.     ->  seeing(Old), see(pipe(Command)),
  599.         $open_source_call(File, Goal, True),
  600.         seen, see(Old), !,
  601.         True == yes
  602.     ;   $warning('Illegal preprocessor specification: `~w''', [Pre]),
  603.         fail
  604.     ).
  605.  
  606.  
  607. $open_source_call(File, Goal, Status) :-
  608.     flag($compilation_level, Level, Level+1),
  609.     ignore(user:$start_compilation(File, Level)),
  610.     (   Goal
  611.     ->  Status = yes
  612.     ;   Status = no
  613.     ),
  614.     ignore(user:$end_compilation(File, Level)),
  615.     flag($compilation_level, _, Level).
  616.  
  617.  
  618. $substitute_atom(Old, New, Org, Result) :-
  619.     name(Old, OS),
  620.     name(New, NS),
  621.     name(Org, OrgS),
  622.     append(Before, Rest, OrgS),
  623.     append(OS, After, Rest), !,
  624.     append(Before, NS, R1),
  625.     append(R1, After, R2), !,
  626.     name(Result, R2).
  627.  
  628.  
  629.         /********************************
  630.         *       LOAD PREDICATES         *
  631.         *********************************/
  632.  
  633. :- module_transparent
  634.     ensure_loaded/1,
  635.     '.'/2,
  636.     consult/1,
  637.     use_module/1,
  638.     use_module/2,
  639.     $load_file/2,
  640.     load_files/1,
  641.     load_files/2.
  642.  
  643. %    ensure_loaded(+File|+ListOfFiles)
  644. %    
  645. %    Load specified files, provided they where not loaded before. If the
  646. %    file is a module file import the public predicates into the context
  647. %    module.
  648.  
  649. ensure_loaded(Files) :-
  650.     load_files(Files, [if(changed)]).
  651.  
  652. %    use_module(+File|+ListOfFiles)
  653. %    
  654. %    Very similar to ensure_loaded/1, but insists on the loaded file to
  655. %    be a module file. If the file is already imported, but the public
  656. %    predicates are not yet imported into the context module, then do
  657. %    so.
  658.  
  659. use_module(Files) :-
  660.     load_files(Files, [if(changed), must_be_module(true)]).
  661.  
  662. %    use_module(+File, +ImportList)
  663. %    
  664. %    As use_module/1, but takes only one file argument and imports only
  665. %    the specified predicates rather than all public predicates.
  666.  
  667. use_module(Files, Import) :-
  668.     load_files(Files, [ if(changed),
  669.                 must_be_module(true),
  670.                 imports(Import)]).
  671.  
  672. [F|R] :-
  673.     consult([F|R]).
  674. [].
  675.  
  676. consult(List) :-
  677.     load_files(List).
  678.  
  679. %    Compilation extensions
  680.  
  681. $compiler_extension('.qlf', $qload_file).
  682. $compiler_extension('',  $consult_file).
  683.  
  684. $consult_goal(Path, Goal) :-
  685.     $compiler_extension(Ext, Goal),
  686.     concat(_, Ext, Path), !.
  687.  
  688.  
  689. %    $consult_file(+File, +Options)
  690. %    
  691. %    Common entry for all the consult derivates.  File is the raw user
  692. %    specified file specification, possibly tagged with the module.
  693. %    
  694. %    `Options' is a list of additional options.  Defined values are
  695. %
  696. %        verbose        Print statistics on user channel
  697. %        is_module        File MUST be a module file
  698. %        import = List    List of predicates to import
  699.  
  700. load_files(Files) :-
  701.     load_files(Files, []).
  702. load_files(Files, Options) :-
  703.     $strip_module(Files, Module, TheFiles),
  704.         $load_files(TheFiles, Module, Options).
  705.  
  706. $load_files([], _, _) :- !.
  707. $load_files([H|T], Module, Options) :- !,
  708.     $load_file(Module:H, Options),
  709.     $load_files(T, Module, Options).
  710. $load_files(File, Module, Options) :-
  711.     $load_file(Module:File, Options).
  712.  
  713.  
  714. $get_option(Term, Options, Default) :-
  715.     (   memberchk(Term, Options)
  716.     ->  true
  717.     ;   arg(1, Term, Default)
  718.     ).
  719.  
  720.  
  721. $noload(true, _) :- !,
  722.     fail.
  723. $noload(not_loaded, FullFile) :-
  724.     source_file(FullFile), !.
  725. $noload(changed, FullFile) :-
  726.     $time_source_file(FullFile, LoadTime),
  727.         time_file(FullFile, Modified),
  728.         Modified @=< LoadTime, !.
  729.  
  730. :- flag($load_silent, _, false).
  731.  
  732. $load_file(Spec, Options) :-
  733.     statistics(heapused, OldHeap),
  734.     statistics(cputime, OldTime),
  735.  
  736.     $get_option(imports(Import), Options, all),
  737.     $get_option(must_be_module(IsModule), Options, false),
  738.     flag($load_silent, DefSilent, DefSilent),
  739.     $get_option(silent(Silent), Options, DefSilent),
  740.     flag($load_silent, _, Silent),
  741.     $get_option(if(If), Options, true),
  742.  
  743.         $strip_module(Spec, Module, File),
  744.         
  745.     (   once($chk_file(File, ['.pl', ''], exists, FullFile)),
  746.         $noload(If, FullFile)
  747.     ->  (   $current_module(LoadModule, FullFile)
  748.         ->  $import_list(Module, LoadModule, all)
  749.         ;   (   Module == user
  750.         ->  true
  751.         ;   $load_file(Spec, [if(true)|Options])
  752.         )
  753.         )
  754.     ;   (   $check_file(File, Absolute)
  755.         *-> true
  756.         ;   $warning('No such file: ~w', Spec),
  757.         fail
  758.         ),
  759.  
  760.         $calleventhook(load_file(Absolute, start)),
  761.         (   $consult_goal(Absolute, Goal),
  762.             $apply(Goal, [Absolute, Module, Import, IsModule, Action, LM])
  763.         ->  true
  764.         ;   $warning('Failed to load file: ~w', Spec),
  765.         $calleventhook(load_file(Absolute, false)),
  766.         fail
  767.         ),
  768.         $calleventhook(load_file(Absolute, true)),
  769.  
  770.         (   Silent == false,
  771.         (flag($autoloading, 0, 0) ; flag($verbose_autoload, on, on))
  772.         ->  statistics(heapused, Heap),
  773.         statistics(cputime, Time),
  774.         HeapUsed is Heap - OldHeap,
  775.         TimeUsed is Time - OldTime,
  776.         $confirm_file(File, Absolute, ConfirmFile),
  777.         $confirm_module(LM, ConfirmModule),
  778.  
  779.         $ttyformat('~N~w ~w~w, ~2f sec, ~D bytes.~n',
  780.                [ConfirmFile, Action, ConfirmModule,
  781.                 TimeUsed, HeapUsed])
  782.         ;   true
  783.         )
  784.     ),
  785.     flag($load_silent, _, DefSilent).
  786.  
  787.  
  788. $confirm_file(library(_), Absolute, Absolute) :- !.
  789. $confirm_file(File, _, File).
  790.  
  791. $confirm_module(user, '') :- !.
  792. $confirm_module(Module, Message) :-
  793.     atom(Module), !,
  794.     concat(' into ', Module, Message).
  795. $confirm_module(_, '').
  796.  
  797. $read_clause(Clause) :-                % get the first non-syntax
  798.     repeat,                    % error
  799.         read_clause(Clause), !.
  800.  
  801. $consult_file(Absolute, Module, Import, IsModule, What, LM) :-
  802.     $set_source_module(Module, Module), !, % same module
  803.     $consult_file_2(Absolute, Module, Import, IsModule, What, LM).
  804. $consult_file(Absolute, Module, Import, IsModule, What, LM) :-
  805.     $set_source_module(OldModule, Module),
  806.     $ifcompiling($qlf_start_sub_module(Module)),
  807.         $consult_file_2(Absolute, Module, Import, IsModule, What, LM),
  808.     $ifcompiling($qlf_end_part),
  809.     $set_source_module(_, OldModule).
  810.  
  811. $consult_file_2(Absolute, Module, Import, IsModule, What, LM) :-
  812.     $set_source_module(OldModule, Module),    % Inform C we start loading
  813.     $start_consult(Absolute),
  814.     $compile_type(What),
  815.     (   flag($compiling, wic, wic)    % TBD
  816.     ->  $add_directive_wic($assert_load_context_module(Absolute,OldModule))
  817.     ;   true
  818.     ),
  819.     $assert_load_context_module(Absolute, OldModule),
  820.  
  821.     $style_check(OldStyle, OldStyle),    % Save style parameters
  822.     $open_source(Absolute, (        % Load the file
  823.         $read_clause(First),
  824.         $load_file(First, Absolute, Import, IsModule, LM))),
  825.     $style_check(_, OldStyle),        % Restore old style
  826.     $set_source_module(_, OldModule).    % Restore old module
  827.  
  828. $compile_type(What) :-
  829.     flag($compiling, How, How),
  830.     (   How == database
  831.     ->  What = compiled
  832.     ;   How == qlf
  833.     ->  What = '*qcompiled*'
  834.     ;   What = 'boot compiled'
  835.     ).
  836.  
  837. %    $load_context_module(+File, -Module)
  838. %    Record the module a file was loaded from (see make/0)
  839.  
  840. $load_context_module(File, Module) :-
  841.     recorded($load_context_module, File/Module, _).
  842.  
  843. $assert_load_context_module(File, Module) :-
  844.     recorded($load_context_module, File/Module, _), !.
  845. $assert_load_context_module(File, Module) :-
  846.     recordz($load_context_module, File/Module, _).
  847.  
  848. %   $load_file(+FirstTerm, +Path, +Import, +IsModule, -Module)
  849. %
  850. %   $load_file5 does the actual loading. The first term has already been
  851. %   read as this may be the module declaraction.
  852.  
  853. $load_file((?- module(Module, Public)), File, all, _, Module) :- !,
  854.     $load_module(Module, Public, all, File).
  855. $load_file((:- module(Module, Public)), File, all, _, Module) :- !,
  856.     $load_module(Module, Public, all, File).
  857. $load_file((?- module(Module, Public)), File, Import, _, Module) :- !,
  858.     $load_module(Module, Public, Import, File).
  859. $load_file((:- module(Module, Public)), File, Import, _, Module) :- !,
  860.     $load_module(Module, Public, Import, File).
  861. $load_file(_, File, _, true, _) :- !,
  862.     $warning('use_module: ~w is not a module file', [File]),
  863.     fail.
  864. $load_file(end_of_file, _, _, _, Module) :- !,        % empty file
  865.     $set_source_module(Module, Module).
  866. $load_file(FirstClause, File, _, false, Module) :- !,
  867.     $set_source_module(Module, Module),
  868.     $ifcompiling($qlf_start_file(File)),
  869.     ignore($consult_clause(FirstClause, File)),
  870.     repeat,
  871.         read_clause(Clause),
  872.         $consult_clause(Clause, File), !,
  873.     $ifcompiling($qlf_end_part).
  874.  
  875.  
  876. $reserved_module(system).
  877. $reserved_module(user).
  878.  
  879. $load_module(Reserved, _, _, _) :-
  880.     $reserved_module(Reserved), !,
  881.     $warning('Cannot load into module "~w": reserved module name',
  882.          [Reserved]),
  883.     fail.
  884. $load_module(Module, Public, Import, File) :-
  885.     $set_source_module(OldModule, OldModule),
  886.     $declare_module(Module, File),
  887.     $export_list(Module, Public),
  888.     $ifcompiling($qlf_start_module(Module)),
  889.  
  890.     repeat,
  891.         read_clause(Clause),
  892.         $consult_clause(Clause, File), !,
  893.  
  894.     Module:$check_export,
  895.     $ifcompiling($qlf_end_part),
  896.     $import_list(OldModule, Module, Import).
  897.  
  898.  
  899. $import_list(_, _, []) :- !.
  900. $import_list(Module, Source, [Name/Arity|Rest]) :- !,
  901.     functor(Term, Name, Arity),
  902.     $import_wic(Source, Term),
  903.     ignore(Module:import(Source:Term)),
  904.     $import_list(Module, Source, Rest).
  905. $import_list(Context, Module, all) :- !,
  906.     export_list(Module, Exports),
  907.     $import_all(Exports, Context, Module).
  908.  
  909.  
  910. $import_all([], _, _).
  911. $import_all([Head|Rest], Context, Source) :-
  912.     ignore(Context:import(Source:Head)),
  913.     $import_wic(Source, Head),
  914.     $import_all(Rest, Context, Source).
  915.  
  916.  
  917. $export_list(_, []) :- !.
  918. $export_list(Module, [Name/Arity|Rest]) :- !,
  919.     functor(Term, Name, Arity),
  920.     export(Module:Term),
  921.     $export_list(Module, Rest).
  922. $export_list(Module, [Term|Rest]) :-
  923.     $warning('Illegal predicate specification in public list: `~w''',
  924.          [Term]),
  925.     $export_list(Module, Rest).
  926.  
  927. $consult_clause(Clause, File) :-
  928.     expand_term(Clause, Expanded),
  929.     (   $store_clause(Expanded, File)
  930.     ->  Clause == end_of_file
  931.     ;   fail
  932.     ).
  933.  
  934. $execute_directive(Goal) :-
  935.     compiling, !,
  936.     $add_directive_wic2(Goal, Type),
  937.     (   Type == call        % suspend compiling into .qlf file
  938.     ->  flag($compiling, Old, database),
  939.         (    $execute_directive2(Goal)
  940.         ->    flag($compiling, _, Old)
  941.         ;    flag($compiling, _, Old),
  942.         fail
  943.         )
  944.     ;   $execute_directive2(Goal)
  945.     ).
  946. $execute_directive(Goal) :-
  947.     $execute_directive2(Goal).
  948.  
  949. $execute_directive2(Goal) :-
  950.     $set_source_module(Module, Module),
  951.     catch(Module:Goal, Term, $exception_in_directive(Term)), !.
  952. $execute_directive2(Goal) :-
  953.     $set_source_module(Module, Module),
  954.     (   Module == user
  955.     ->  $warning('Directive failed: ~w', [Goal])
  956.     ;   $warning('Directive failed: ~w:~w', [Module, Goal])
  957.         ),
  958.     fail.
  959.  
  960. $exception_in_directive(Term) :-
  961.     print_message(error, Term),
  962.     fail.
  963.  
  964. %    Note that the list, consult and ensure_loaded directives are already
  965. %    handled at compile time and therefore should not go into the
  966. %    intermediate code file.
  967.  
  968. $add_directive_wic2(Goal, Type) :-
  969.     $common_goal_type(Goal, Type), !,
  970.     (   Type == load
  971.     ->  true
  972.     ;   $set_source_module(Module, Module),
  973.         $add_directive_wic(Module:Goal)
  974.     ).
  975. $add_directive_wic2(Goal, _) :-
  976.     (   flag($compiling, qlf, qlf)    % no problem for qlf files
  977.     ->  true
  978.     ;   $warning('Cannot compile mixed loading/calling directives: ~w',
  979.              [Goal])
  980.     ).
  981.     
  982. $common_goal_type((A,B), Type) :- !,
  983.     $common_goal_type(A, Type),
  984.     $common_goal_type(B, Type).
  985. $common_goal_type((A;B), Type) :- !,
  986.     $common_goal_type(A, Type),
  987.     $common_goal_type(B, Type).
  988. $common_goal_type((A->B), Type) :- !,
  989.     $common_goal_type(A, Type),
  990.     $common_goal_type(B, Type).
  991. $common_goal_type(Goal, Type) :-
  992.     $goal_type(Goal, Type).
  993.  
  994. $goal_type(Goal, Type) :-
  995.     (   $load_goal(Goal)
  996.     ->  Type = load
  997.     ;   Type = call
  998.     ).
  999.  
  1000. $load_goal([_|_]).
  1001. $load_goal(consult(_)).
  1002. $load_goal(ensure_loaded(_)) :- flag($compiling, wic, wic).
  1003. $load_goal(use_module(_))    :- flag($compiling, wic, wic).
  1004. $load_goal(use_module(_, _)) :- flag($compiling, wic, wic).
  1005.  
  1006.         /********************************
  1007.         *        TERM EXPANSION         *
  1008.         *********************************/
  1009.  
  1010. :- user:dynamic(term_expansion/2).
  1011. :- user:multifile(term_expansion/2).
  1012.  
  1013. expand_term(Term, Expanded) :-        % local term-expansion
  1014.     $term_expansion_module(Module),
  1015.     Module:term_expansion(Term, Expanded), !.
  1016. expand_term(Term, Expanded) :-
  1017.     $translate_rule(Term, Expanded), !.
  1018. expand_term(Term, Term).
  1019.  
  1020. $store_clause([], _) :- !.
  1021. $store_clause([C|T], F) :- !,
  1022.     $store_clause(C, F),
  1023.     $store_clause(T, F).
  1024. $store_clause(end_of_file, _) :- !.
  1025. $store_clause((:- Goal), _) :- !,
  1026.     $execute_directive(Goal).
  1027. $store_clause((?- Goal), _) :- !,
  1028.     $execute_directive(Goal).
  1029. $store_clause((_, _), _) :- !,
  1030.     $warning('Full stop in clause body? (attempt to define ,/2)').
  1031. $store_clause((_:-B), _) :-
  1032.     nonvar(B), B = (_:-_), !,
  1033.     $warning('Clause not closed by `.''? (attempt to call :-/2)').
  1034. $store_clause($source_location(File, Line):Term, _) :-
  1035.     $record_clause(Term, File:Line, Ref),
  1036.         $ifcompiling($qlf_assert_clause(Ref)).
  1037. $store_clause(Term, File) :-
  1038.     $record_clause(Term, File, Ref),
  1039.         $ifcompiling($qlf_assert_clause(Ref)).
  1040.  
  1041.          /*******************************
  1042.          *     FOREIGN INTERFACE    *
  1043.          *******************************/
  1044.  
  1045. %    call-back from PL_register_foreign().  First argument is the module
  1046. %    into which the foreign predicate is loaded and second is a term
  1047. %    describing the arguments.
  1048.  
  1049. :- dynamic
  1050.     $foreign_registered/2.
  1051.  
  1052.  
  1053.         /********************************
  1054.         *        GRAMMAR RULES          *
  1055.         *********************************/
  1056.  
  1057. /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  1058. The DCG compiler. The original code was copied from C-Prolog and written
  1059. by Fernando Pereira, EDCAAD, Edinburgh,  1984.   Since  then many people
  1060. have modified and extended this code. It's a nice mess now and it should
  1061. be redone from scratch. I won't be doing   this  before I get a complete
  1062. spec explaining all an implementor needs to   know  about DCG. I'm a too
  1063. basic user of this facility myself (though   I  learned some tricks from
  1064. people reporting bugs :-)
  1065.  
  1066. The original version contained  $t_tidy/2  to   convert  ((a,b),  c)  to
  1067. (a,(b,c)), but as the  SWI-Prolog  compiler   doesn't  really  care (the
  1068. resulting code is simply the same), I've removed that.
  1069. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  1070.  
  1071. $translate_rule((LP-->List), H) :-
  1072.     proper_list(List), !,
  1073.     (   List = []
  1074.     ->  $t_head(LP, S, S, H)
  1075.     ;   List = [X]
  1076.     ->  $t_head(LP, [X|S], S, H)
  1077.     ;   append(List, SR, S),
  1078.         $extend([S, SR], LP, H)
  1079.     ), !.
  1080. $translate_rule((LP-->RP), (H:-B)):-
  1081.     $t_head(LP, S, SR, H),
  1082.     $t_body(RP, S, SR, B).
  1083.  
  1084. $tailvar(X, X) :-
  1085.     var(X), !.
  1086. $tailvar([_|T], V) :-
  1087.     $tailvar(T, V).
  1088.  
  1089. $t_head((LP, List), S, SR, H) :-
  1090.     append(List, SR, List2), !,
  1091.     $extend([S, List2], LP, H).
  1092. $t_head(LP, S, SR, H) :-
  1093.     $extend([S, SR], LP, H).
  1094.  
  1095.  
  1096. $t_body(Var, S, SR, phrase(Var, S, SR)) :-
  1097.     var(Var), !.
  1098. $t_body(List, S, SR, C) :-
  1099.     proper_list(List), !,
  1100.     (   List = []
  1101.     ->  C = (S=SR)
  1102.     ;   List = [X]
  1103.     ->  C = 'C'(S, X, SR)
  1104.     ;   C = append(List, SR, S)
  1105.     ).
  1106. $t_body(List, S, SR, C) :-
  1107.     List = [_|_], !,
  1108.     C = append(List, SR, S).
  1109. $t_body(!, S, S, !) :- !.
  1110. $t_body({T}, S, SR, (T, SR = S)) :- !.
  1111. $t_body((T, R), S, SR, (Tt, Rt)) :- !,
  1112.     $t_body(T, S, SR1, Tt),
  1113.     $t_body(R, SR1, SR, Rt).
  1114. $t_body((T;R), S, SR, (Tt;Rt)) :- !,
  1115.     $t_body(T, S, S1, T1), $t_fill(S, SR, S1, T1, Tt),
  1116.     $t_body(R, S, S2, R1), $t_fill(S, SR, S2, R1, Rt).
  1117. $t_body((T|R), S, SR, (Tt;Rt)) :- !,
  1118.     $t_body(T, S, S1, T1), $t_fill(S, SR, S1, T1, Tt),
  1119.     $t_body(R, S, S2, R1), $t_fill(S, SR, S2, R1, Rt).
  1120. $t_body((C->T;E), S, SR, (Ct->Tt;Et)) :- !,
  1121.     $t_body(C, S, S1, Ct),
  1122.     $t_body(T, S1, S2, T1), $t_fill(S, SR, S2, T1, Tt),
  1123.     $t_body(E, S1, S3, E1), $t_fill(S, SR, S3, E1, Et).
  1124. $t_body((C->T|E), S, SR, (Ct->Tt;Et)) :- !,
  1125.     $t_body(C, S, S1, Ct),
  1126.     $t_body(T, S1, S2, T1), $t_fill(S, SR, S2, T1, Tt),
  1127.     $t_body(E, S1, S3, E1), $t_fill(S, SR, S3, E1, Et).
  1128. $t_body((C->T), S, SR, (Ct->Tt)) :- !,
  1129.     $t_body(C, S, SR1, Ct),
  1130.     $t_body(T, SR1, SR, Tt).
  1131. $t_body((\+ C), S, SR, (\+ Ct)) :- !,
  1132.     $t_body(C, S, SR, Ct).
  1133. $t_body(T, S, SR, Tt) :-
  1134.     $extend([S, SR], T, Tt).
  1135.  
  1136.  
  1137. $t_fill(S, SR, S1, T, (T, SR=S)) :-
  1138.     S1 == S, !.
  1139. $t_fill(_S, SR, SR, T, T).
  1140.  
  1141.  
  1142. $extend(More, OldT, NewT) :-
  1143.     OldT =.. OldL,
  1144.     append(OldL, More, NewL),
  1145.     NewT =.. NewL.
  1146.  
  1147. 'C'([X|S], X, S).
  1148.  
  1149. :- module_transparent
  1150.     phrase/2,
  1151.     phrase/3.
  1152.  
  1153. phrase(RuleSet, Input) :-
  1154.     phrase(RuleSet, Input, []).
  1155. phrase(RuleSet, Input, Rest) :-
  1156.     $strip_module(RuleSet, _, Head),
  1157.     (   is_list(Head)
  1158.     ->  append(Head, Rest, Input)
  1159.     ;   call(RuleSet, Input, Rest)
  1160.     ).
  1161.  
  1162.  
  1163.         /********************************
  1164.         *     WIC CODE COMPILER         *
  1165.         *********************************/
  1166.  
  1167. /*  This  entry  point  is  called  from  pl-main.c  if  the  -c  option
  1168.     (intermediate  code  compilation) is given.  It's job is simple: get
  1169.     the output file  and  input  files,  open  the  output  file,  setup
  1170.     intermediate  code  compilation  flag  and  finally just compile the
  1171.     input files.
  1172. */
  1173.  
  1174. $compile_wic :-
  1175.     $argv(Argv),            % gets main() argv as a list of atoms
  1176.     $get_files_argv(Argv, Files),
  1177.     $get_wic_argv(Argv, Wic),
  1178.     $compile_wic(Files, Wic).
  1179.  
  1180. $compile_wic(FileList, Wic) :-
  1181.     $open_wic(Wic, []),
  1182.     $qlf_put_states,        % `W state' directives
  1183.     flag($compiling, Old, wic),
  1184.         $style_check(Style, Style),
  1185.         $execute_directive($style_check(_, Style)),
  1186.         user:consult(FileList),
  1187.     flag($compiling, _, Old),
  1188.     $close_wic.
  1189.  
  1190. $get_files_argv([], []) :- !.
  1191. $get_files_argv(['-c'|Files], Files) :- !.
  1192. $get_files_argv([_|Rest], Files) :-
  1193.     $get_files_argv(Rest, Files).
  1194.  
  1195. $get_wic_argv([], 'a.out').
  1196. $get_wic_argv(['-o', Wic|_], Wic) :- !.
  1197. $get_wic_argv([_|Rest], Wic) :-
  1198.     $get_wic_argv(Rest, Wic).
  1199.  
  1200.  
  1201.         /********************************
  1202.         *       LIST PROCESSING         *
  1203.         *********************************/
  1204.  
  1205. member(X, [X|_]).
  1206. member(X, [_|T]) :-
  1207.     member(X, T).
  1208.  
  1209. append([], L, L).
  1210. append([H|T], L, [H|R]) :-
  1211.     append(T, L, R).
  1212.  
  1213.  
  1214.          /*******************************
  1215.          *           HALT        *
  1216.          *******************************/
  1217.  
  1218. halt :-
  1219.     halt(0).
  1220.  
  1221.  
  1222. :- module_transparent
  1223.     at_halt/1.
  1224. :- dynamic
  1225.     $at_halt/1.
  1226.  
  1227. at_halt(Spec) :-
  1228.     $strip_module(Spec, Module, Goal),
  1229.     assert(system:$at_halt(Module:Goal)).
  1230.  
  1231. $run_at_halt :-
  1232.     $at_halt(Goal),
  1233.     Goal,
  1234.     fail ; true.
  1235.  
  1236.  
  1237.         /********************************
  1238.         *      LOAD OTHER MODULES       *
  1239.         *********************************/
  1240.  
  1241. :- module_transparent
  1242.     $load_wic_files/2,
  1243.     $load_additional_boot_files/0.
  1244.  
  1245. $load_wic_files(Module, Files) :-
  1246.     $execute_directive($set_source_module(OldM, Module)),
  1247.     $style_check(OldS, 2'1111),
  1248.     flag($compiling, OldC, wic),
  1249.     consult(Files),
  1250.     $execute_directive($set_source_module(_, OldM)),
  1251.     $execute_directive($style_check(_, OldS)),
  1252.     flag($compiling, _, OldC).
  1253.  
  1254.  
  1255. $load_additional_boot_files :-
  1256.     $argv(Argv),
  1257.     $get_files_argv(Argv, Files),
  1258.     (   Files \== []
  1259.     ->  format('Loading additional boot files~n'),
  1260.         $load_wic_files(user, Files),
  1261.         format('additional boot files loaded~n')
  1262.     ;   true
  1263.         ).
  1264.  
  1265.  
  1266. '$:-'    
  1267.     format('Loading Prolog startup files~n', []),
  1268.     source_location(File, _Line),
  1269.     file_directory_name(File, Dir),
  1270.     concat(Dir, '/load.pl', LoadFile),
  1271.     $load_wic_files(system, [LoadFile]),
  1272.     format('SWI-Prolog boot files loaded~n', []),
  1273.     flag($compiling, OldC, wic),
  1274.     $execute_directive($set_source_module(_, user)),
  1275.     flag($compiling, _, OldC).
  1276.